﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace DimensionsHelper.Services.CsvReader;

public static partial class CsvHelper
{
    private static readonly char[] Delimiters =
    [
        ';',
        ',',
        '|',
        '\t'
    ];

    private static string Read(ref int pos, int line, string text, char delimiter)
    {
        var start = pos;

        var cur = text[pos];
        var doubleQuoted = false;
        var doubleQuoteEnd = false;

        if (cur == '"')
        {
            doubleQuoted = true;
            pos++;
        }

        while (pos < text.Length)
        {
            cur = text[pos];

            if (doubleQuoted && doubleQuoteEnd && cur != delimiter)
            {
                throw new Exception($"应为'{delimiter}'：行 - {line}，字符 - {pos}");
            }

            if ((!doubleQuoted || doubleQuoteEnd) && cur == delimiter)
            {
                break;
            }

            if (doubleQuoted && pos < text.Length - 1 && cur == '"' && text[pos + 1] == '"')
            {
                pos += 2;
            }
            else if (doubleQuoted && cur == '"')
            {
                doubleQuoteEnd = true;
                pos++;
            }
            else
            {
                pos++;
            }
        }

        if (doubleQuoted && !doubleQuoteEnd)
        {
            throw new Exception($"未终结的双引号：行 - {line}，字符 - {pos}");
        }

        var final = doubleQuoted ? text.Substring(start + 1, pos - start - 2) : text[start..pos];
        return final.Replace("\"\"", "\"");
    }

    public static void ReadLine(string text, char delimiter, int line, Action<string> callback)
    {
        var pos = 0;

        while (pos < text.Length)
        {
            callback.Invoke(Read(ref pos, line, text, delimiter));
            pos++;
        }
    }

    private static int GetColumnsByDelimiter(string text, int line, char delimiter)
    {
        var count = 0;
        ReadLine(text, delimiter, line, _ => count++);
        return count;
    }

    public static char GetDelimiter(IEnumerable<string> contents)
    {
        const char delimiter = ',';
        var delimiterColumnCounts = Delimiters.ToDictionary(d => d, _ => 0);
        var line = 0;

        foreach (var text in contents)
        {
            var regex = StringRegex();
            var match = regex.Match(text);

            if (match.Success && match.Index + match.Length < text.Length)
            {
                var c = text[match.Index + match.Length];
                if (Delimiters.Contains(c))
                {
                    return c;
                }
            }

            foreach (var d in Delimiters)
            {
                delimiterColumnCounts[d] = GetColumnsByDelimiter(text, line, d);
            }

            var ordered = delimiterColumnCounts.OrderByDescending(c => c.Value).ToArray();

            if (ordered[0].Value > 2 && ordered[1].Value < ordered[0].Value)
            {
                return ordered[0].Key;
            }

            line++;
        }

        return delimiter;
    }

    public static bool IsStringSignificantResult(string text)
    {
        return !string.IsNullOrEmpty(text) && SigResultRegex().IsMatch(text);
    }

    [GeneratedRegex("\".*?\"")]
    private static partial Regex StringRegex();
    
    [GeneratedRegex(@"[a-zA-Z]*\*{0,2}")]
    private static partial Regex SigResultRegex();
}